/**
  ******************************************************************************
* @file				iic_oled.c
* @Software			MDK V5
* @Target 			CW32F030
* @author			ou_teki
* @encoding			UTF-8
* @date				2024-0420
  ******************************************************************************
  */

#include "iic_oled.h"

uint8_t	u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
uint8_t u8g2_gpio_and_dealy_cw32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);

//-TKW24-0716-IIC Init
//-I2C2_SDA->PB7  I2C2_SCL-PB6 
uint8_t OLED_IIC_Init(void)
{
    //时钟初始化
    __RCC_I2C1_CLK_ENABLE();    //
    //I2C的IO口初始化
    GPIO_InitTypeDef gpio_init_s;
    PB06_AFx_I2C1SCL();
    PB07_AFx_I2C1SDA();
    gpio_init_s.IT = GPIO_IT_NONE;
    gpio_init_s.Pins = GPIO_PIN_6 | GPIO_PIN_7;
    gpio_init_s.Mode = GPIO_MODE_OUTPUT_PP; //GPIO_MODE_OUTPUT_OD;  //
    gpio_init_s.Speed = GPIO_SPEED_HIGH;
    GPIO_Init(CW_GPIOB, &gpio_init_s);
    //I2C初始化
    I2C_InitTypeDef iic_init_s;
    iic_init_s.I2C_BaudEn = ENABLE;
    iic_init_s.I2C_Baud = 0x01;  //500K=(8000000/(8*(1+1))
    iic_init_s.I2C_FLT = DISABLE;
    iic_init_s.I2C_AA = DISABLE;

    I2C1_DeInit();
    I2C_Master_Init(CW_I2C1, &iic_init_s); //初始化模块
    I2C_Cmd(CW_I2C1, ENABLE); //模块使能
        // I2C_MasterSendDataToSlave(CW_I2C1, u8Senddata, 16); //主机发送16字节数据
    return 0;
}

//-TKW24-0716-IIC Send Data
uint8_t OLED_IIC_SendData(I2C_TypeDef *iicx, uint8_t addr, uint8_t *p_data, uint32_t len)
{
    uint32_t u32i = 1;
    uint8_t u8State;
    I2C_GenerateSTART(iicx, ENABLE);
    while (1)
    {
     
        while (0 == I2C_GetIrq(iicx))
        {;}
LOOP1:
        u8State = I2C_GetState(iicx);
        
        switch (u8State)
        {
            case 0x08:   //发送完START信号
                I2C_GenerateSTART(iicx, DISABLE);
                I2C_Send7bitAddress(iicx, addr, 0X00); //从设备地址+W发送
                break;
            case 0x18:   //发送完SLA+W信号
                I2C_SendData(iicx, p_data[u32i - 1]);
                u32i++;
                break;            
            case 0x28:   //发送完1字节数据：发送EEPROM中memory地址也会产生，发送后面的数据也会产生
START:
                I2C_SendData(iicx, p_data[u32i - 1]);
                while (0 == I2C_GetIrq(iicx));                
                I2C_GenerateSTOP(iicx, ENABLE);               
                u32i++;
                I2C_ClearIrq(iicx);
                goto LOOP1;
                break;
            case 0x20:   //发送完SLA+W后从机返回NACK
            case 0x38:   //主机在发送 SLA+W 阶段或者发送数据阶段丢失仲裁  或者  主机在发送 SLA+R 阶段或者回应 NACK 阶段丢失仲裁
                I2C_GenerateSTART(iicx, ENABLE);
                break;
            case 0x30:   //发送完一个数据字节后从机返回NACK
                I2C_GenerateSTOP(iicx, ENABLE);
                break;
            case 0xF8:
//                I2C_GenerateSTART(iicx, ENABLE);
            goto START;
                
            default:
                break;
        }
        if (u32i > len)
        {
            I2C_GenerateSTOP(iicx, ENABLE);//此顺序不能调换，出停止条件
            I2C_ClearIrq(iicx);
            break;
        }
        I2C_ClearIrq(iicx);
        
    }
    
    return 0;
}


//-TKW24-1109-U8G2_SSD1306_I2C Init
uint8_t OLED_U8G2_Init(u8g2_t *p_u8g2)
{
	u8g2_Setup_ssd1306_i2c_128x64_noname_f(p_u8g2, U8G2_R1, u8x8_byte_hw_i2c, u8g2_gpio_and_dealy_cw32);
	u8g2_InitDisplay(p_u8g2);
	u8g2_SetPowerSave(p_u8g2, 0);
	u8g2_ClearBuffer(p_u8g2);


	
	draw(p_u8g2);
	// HAL_Delay(1000);
	// u8g2_ClearBuffer(p_u8g2);
	// u8g2_SetFont(p_u8g2, u8g2_font_ncenB08_tf);
	// u8g2_DrawStr(p_u8g2, 0, 8, "STM32 F103");
	// PrintVarFormat(p_u8g2, 50, 30, u8g2_font_sirclivethebold_tr, 2);
	// u8g2_DrawStr(p_u8g2, 0, 50, "OLED display");
	// u8g2_SendBuffer(p_u8g2); 

    return 0;
}


uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
  static uint8_t buffer[32];	/* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
  static uint8_t buf_idx;
  uint8_t *data;
 
  switch(msg)
  {
    case U8X8_MSG_BYTE_SEND:
      data = (uint8_t *)arg_ptr;      
      while( arg_int > 0 )
      {
	        buffer[buf_idx++] = *data;
	        data++;
	        arg_int--;
      }      
    break;
			
    case U8X8_MSG_BYTE_INIT:
      /* add your custom code to init i2c subsystem */
    break;
		
    case U8X8_MSG_BYTE_SET_DC:
      /* ignored for i2c */
    break;
		
    case U8X8_MSG_BYTE_START_TRANSFER:
      buf_idx = 0;
    break;
		
    case U8X8_MSG_BYTE_END_TRANSFER:
    //   buffer[0] =  u8x8_GetI2CAddress(u8x8);
      OLED_IIC_SendData(CW_I2C1, u8x8_GetI2CAddress(u8x8)>>1, buffer, buf_idx);
    break;
		
    default:		return 0;
  }
  return 1;
}


uint8_t u8g2_gpio_and_dealy_cw32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{

	switch(msg)
	{
		
		case U8X8_MSG_GPIO_AND_DELAY_INIT:
		break;
			
		case U8X8_MSG_DELAY_MILLI:
			//HAL_Delay(arg_int);
		break;
			
		case U8X8_MSG_GPIO_I2C_CLOCK:		
		break;							
			
		case U8X8_MSG_GPIO_I2C_DATA:			
		break;
			
		default:		return 0;
	}
	
	return 1; // command processed successfully.
}


uint8_t draw(u8g2_t *p_u8g2)
{
    u8g2_SetFontMode(p_u8g2, 1); /*字体模式选择*/
    u8g2_SetFontDirection(p_u8g2, 0); /*字体方向选择*/
    u8g2_SetFont(p_u8g2, u8g2_font_inb24_mf); /*字库选择*/
    u8g2_DrawStr(p_u8g2, 0, 20, "U");
    
    u8g2_SetFontDirection(p_u8g2, 1);
    u8g2_SetFont(p_u8g2, u8g2_font_inb30_mn);
    u8g2_DrawStr(p_u8g2, 21,8,"8");
        
    u8g2_SetFontDirection(p_u8g2, 0);
    u8g2_SetFont(p_u8g2, u8g2_font_inb24_mf);
    u8g2_DrawStr(p_u8g2, 51,30,"g");
    u8g2_DrawStr(p_u8g2, 67,30,"\xb2");
    
    u8g2_DrawHLine(p_u8g2, 2, 35, 47);
    u8g2_DrawHLine(p_u8g2, 3, 36, 47);
    u8g2_DrawVLine(p_u8g2, 45, 32, 12);
    u8g2_DrawVLine(p_u8g2, 46, 33, 12);
  
    u8g2_SetFont(p_u8g2, u8g2_font_4x6_tr);
    u8g2_DrawStr(p_u8g2, 1,54,"github.com/olikraus/u8g2");
		
	u8g2_SendBuffer(p_u8g2);

    return 0;
}


void PrintVarFormat(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const uint8_t *font, short var)
{
    char var_buff[100];             //用来存ASCII码
    u8g2_SetFont(u8g2, font);       //设定字体
    sprintf(var_buff, "%4d", var);  //传递变量（十进制（占四格））
    u8g2_DrawStr(u8g2, x, y, var_buff); //显示
}






/********************************End of File************************************/


